<template>
  <el-container style="height: 90vh">
    <el-header style="margin-bottom: 5px">
      <el-row style="padding-top: 5px; padding-bottom: 5px">
        <el-card style="width: 100%; text-align: left">
          <span>查询整周：</span>
          <el-switch v-model="ifWholeWeek" />
          <span style="margin-left: 10px">日期：</span>
          <el-date-picker
              v-model="date"
              type="date"
              placeholder="日期"
              :size="'default'"
              style="width: 9vw;"
              format="YYYY/MM/DD"
              value-format="YYYY-MM-DD"
              :disabled="ifWholeWeek"
              :disabled-date="disableFutureDates"
          />
          <el-button @click="selectHotpoint" style="width: 5vw; margin-left: 10px" type="primary">查询</el-button>
        </el-card>
      </el-row>
    </el-header>
    <el-main>
      <el-row :gutter="20" style="margin-bottom: 10px">
        <el-col :span="24">
          <el-card>
            <el-row>
              <el-col :span="6">
                <el-statistic title="舆情情感倾向" :value="mood" :value-style="{ color: moodColor, fontSize: '16px' }" />
              </el-col>
              <el-col :span="6">
                <el-statistic title="热搜总数" :value="hotpointCount" />
              </el-col>
              <el-col :span="6">
                <el-statistic title="热度最高" :value="maxFever" :value-style="{ fontSize: '14px' }" />
              </el-col>
              <el-col :span="6">
                <el-statistic title="最受关注内容" :value="maxCategory" :value-style="{ fontSize: '16px' }" />
              </el-col>
            </el-row>
          </el-card>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <div class="chart-container">
            <div class="chart-wrapper" id="chart1"></div>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="chart-container">
            <div class="chart-wrapper" id="chart2"></div>
          </div>
        </el-col>
      </el-row>
      <el-row :gutter="20" style="margin-top: 10px">
        <el-col :span="12">
          <el-card class="dashboard-card">
            <div class="card-header">
              <div class="card-title">各种类热搜情感分布</div>
            </div>
            <div class="chart-container">
              <div class="chart-wrapper" id="multiBarChart"></div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card class="dashboard-card">
            <div class="card-header">
              <div class="card-title">热搜持续Top10</div>
            </div>
            <div class="chart-container">
              <div class="chart-wrapper" id="barChart"></div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </el-main>
  </el-container>
</template>

<script setup lang="ts">
import * as echarts from "echarts";
import {computed, nextTick, onMounted, ref} from "vue";
import axios from "axios";
import {ElMessage} from "element-plus";
import moment from "moment/moment";
import type {ECharts} from "echarts";

onMounted(() => {
  initChart1()
  initChart2()
  updateBarChart()
  updateMultiBarChart()
})

// 禁用未来日期的方法
const disableFutureDates = (time: Date) => {
  return time.getTime() > Date.now();
};

// 统一的提示内容生成函数
const generateTooltipContent = (params: any) => {
  return `
    <div style="margin: 0; text-align: left; font-family: Arial, sans-serif;">
      <div style="font-size: 14px; color: #666; border-bottom: 1px solid #eee; padding-bottom: 5px; margin-bottom: 5px;">
        ${params.seriesName || '数据项'}
      </div>
      <div style="display: flex; align-items: center; justify-content: flex-start; margin-bottom: 8px;">
        <span style="display: inline-block; width: 10px; height: 10px; background: ${params.color};
              border-radius: 50%; margin-right: 8px; flex-shrink: 0;"></span>
        <span style="font-weight: bold; white-space: nowrap;">${params.name}</span>
      </div>
      <div style="line-height: 1.6">
        <div style="display: flex; justify-content: space-between">
          <span style="color: #999; margin-right: 15px">数量：</span>
          <span style="color: #409EFF">${params.value?.toLocaleString() || '0'}</span>
        </div>
        <div style="display: flex; justify-content: space-between">
          <span style="color: #999; margin-right: 15px">占比：</span>
          <span style="color: #67C23A">${params.percent?.toFixed(2) || '0.00'}%</span>
        </div>
      </div>
    </div>
  `;
};

/**
 * 生成测试数据函数
 * 当API没有返回有效数据时，使用此函数生成测试数据
 * 特点：
 * 1. 数据结构与真实API完全一致
 * 2. 所有数据项都包含"测试"前缀便于识别
 * 3. 数据分布合理，能测试所有图表展示
 */
const generateTestData = () => {
  console.log('[测试模式] 正在生成测试数据...');

  return {
    moodTrend: ['positive', 'neutral', 'negative', 'positive', 'neutral', 'positive', 'neutral'],
    hotpointCount: 350,
    categoryDistribution: {
      '测试-娱乐': 80,
      '测试-科技': 60,
      '测试-体育': 45,
      '测试-财经': 50,
      '测试-社会': 70,
      '测试-健康': 30,
      '测试-教育': 25
    },
    emotionDistribution: {
      positive: 120,
      neutral: 150,
      negative: 80
    },
    top10Hotpoints: [
      { name: '测试热搜1-重大科技突破', value: 48 },
      { name: '测试热搜2-明星演唱会', value: 42 },
      { name: '测试热搜3-体育赛事', value: 38 },
      { name: '测试热搜4-财经新闻', value: 35 },
      { name: '测试热搜5-社会热点', value: 32 },
      { name: '测试热搜6-健康资讯', value: 28 },
      { name: '测试热搜7-教育政策', value: 25 },
      { name: '测试热搜8-娱乐八卦', value: 22 },
      { name: '测试热搜9-科技创新', value: 20 },
      { name: '测试热搜10-国际新闻', value: 18 }
    ],
    categoryEmotion: {
      '测试-娱乐': { positive: 40, neutral: 30, negative: 10 },
      '测试-科技': { positive: 25, neutral: 25, negative: 10 },
      '测试-体育': { positive: 20, neutral: 15, negative: 10 },
      '测试-财经': { positive: 15, neutral: 25, negative: 10 },
      '测试-社会': { positive: 10, neutral: 40, negative: 20 },
      '测试-健康': { positive: 5, neutral: 15, negative: 10 },
      '测试-教育': { positive: 5, neutral: 10, negative: 10 }
    }
  };
};

const ifWholeWeek = ref(false)

// const date = ref(moment().subtract(1, 'day').format('YYYY-MM-DD')) // 日期（与日期选择框绑定）
const date = ref()

const hotpointCount = ref<Number | string>('--')
const maxCategory = ref<Number | string>('--')
const maxFever = ref<Number | string>('--')
const mood = ref<Number | string>('--')
const moodColor = ref()

// 查询热搜分析数据
const selectHotpoint = async () => {
  if (ifWholeWeek.value) {
    // 查询最近7天数据
    const dateList = [];
    for (let i = 7; i >= 1; i--) {
      dateList.push(moment().subtract(i, 'days').format('YYYY-MM-DD'));
    }

    console.log(dateList);

    try {
      // 并行查询每天的数据
      const responses = await Promise.all(
          dateList.map(date =>
              axios.all([
                axios.get(`${window.BASE_URL}/api/hotSearch/getHotDataAndClassifyByDateAndPlatform/${date}`)
                    .then(res => res)
                    .catch(() => ({ data: { flag: false, data: null }})),
                axios.get(`${window.BASE_URL}/api/hotSearch/getCatgoryAndAnalysisByDate/${date}`)
                    .then(res => res)
                    .catch(() => ({ data: { flag: false, data: null }})),
                axios.get(`${window.BASE_URL}/api/hotSearch/getHotDataAndAnalysisByDate/${date}`)
                    .then(res => res)
                    .catch(() => ({ data: { flag: false, data: null }})),
                axios.get(`${window.BASE_URL}/api/hotSearch/getHotDataAndClassifyByDate/${date}`)
                    .then(res => res)
                    .catch(() => ({ data: { flag: false, data: null }})),
                axios.get(`${window.BASE_URL}/api/hotSearch/getHotDataTimeTop/${date}`)
                    .then(res => res)
                    .catch(() => ({ data: { flag: false, data: null }})),
              ])
          )
      );

      console.log('WeekSearchSuccess')

      // 记录有效数据天数
      const validDays = responses.filter(dayResponses =>
          dayResponses.every(res => res?.data?.flag && res?.data?.data !== null)
      ).length;

      if (validDays > 0) {
        processWeekData(responses, dateList);
        ElMessage.success(`成功加载 ${validDays}/7 天的数据`);
        console.log(`成功加载 ${validDays}/7 天的数据`);
      } else {
        ElMessage.warning('没有可用的数据');
        console.log('没有可用的数据');
        console.log('使用测试数据');
        const testData = generateTestData();
        return updateChartsWithWeekData(testData);
      }
    } catch (error) {
      ElMessage.error('聚合数据加载失败');
      console.log('聚合数据加载失败');
      console.error(error);
    }
  }
  else {
    if (date.value === '' || date.value === undefined || date.value === null) {
      ElMessage.warning('请选择日期！')
      return
    }
    Promise.all([
      axios.get(`${window.BASE_URL}/api/hotSearch/getHotDataAndClassifyByDateAndPlatform/${date.value}`),
      axios.get(`${window.BASE_URL}/api/hotSearch/getCatgoryAndAnalysisByDate/${date.value}`),
      axios.get(`${window.BASE_URL}/api/hotSearch/getHotDataAndAnalysisByDate/${date.value}`),
      axios.get(`${window.BASE_URL}/api/hotSearch/getHotDataAndClassifyByDate/${date.value}`),
      axios.get(`${window.BASE_URL}/api/hotSearch/getHotDataTimeTop/${date.value}`)
    ]).then(([response1, response2, response3, response4, response5]) => {
      // console.log('Response 1:', response1.data);
      // console.log('Response 2:', response2.data);
      // console.log('Response 3:', response3.data);
      // console.log('Response 4:', response4.data);
      // console.log('Response 5:', response5.data);

      if (response1.data.flag && response2.data.flag && response3.data.flag) {
        // ----处理 response1 数据----
        maxCategory.value = response1.data.data.maxCategory.category;
        maxFever.value = response1.data.data.maxFever.title;
        hotpointCount.value = response1.data.data.totalCount;

        // ----处理 response2 数据----
        // console.log(response2);
        xAxisData.value = response2.data.data.categories;
        yAxisData_Positive.value = response2.data.data.positive;
        yAxisData_Negative.value = response2.data.data.negative;
        yAxisData_Neutral.value = response2.data.data.neutral;
        // console.log(xAxisData);
        // console.log(yAxisData_Positive);
        // console.log(yAxisData_Neutral);
        // console.log(yAxisData_Negative);
        nextTick(() => {
          updateMultiBarChart();
        })

        // ----处理 response3 数据----
        chartData1.value = [
          {
            value: response3.data.data.Positive,
            name: '积极',
            itemStyle: {
              color: '#67C23A' // Element Plus 的成功色（绿色）
            }
          },
          {
            value: response3.data.data.Neutral,
            name: '中立',
            itemStyle: {
              color: '#909399' // Element Plus 的次要色（灰色）
            }
          },
          {
            value: response3.data.data.Negative,
            name: '消极',
            itemStyle: {
              color: '#F56C6C' // Element Plus 的危险色（红色）
              // 或者使用警告色黄色：#E6A23C
            }
          },
        ];
        nextTick(() => {
          updateChart1()
        });
        mood.value = response3.data.data.Positive > response3.data.data.Negative ? (response3.data.data.Positive > response3.data.data.Neutral ? '积极' : '中立') : response3.data.data.Neutral > response3.data.data.Negative ? '中立' : '消极';
        moodColor.value = response3.data.data.Positive > response3.data.data.Negative ? (response3.data.data.Positive > response3.data.data.Neutral ? '#67C23A' : '#909399') : response3.data.data.Neutral > response3.data.data.Negative ? '#909399' : '#F56C6C';

        // ----处理 response4 数据----
        chartData2.value = response4.data.data.categories;
        nextTick(() => {
          updateChart2()
        })

        // ----处理 response5 数据----
        xAxis.value = response5.data.data.titles;
        yAxis.value = response5.data.data.durations;
        nextTick(() => {
          updateBarChart()
        })
      } else {
        ElMessage.error('数据加载失败');
        console.log('数据加载失败');
      }
    }).catch(error => {
      console.error('请求出错:', error);
      ElMessage.error('数据加载失败');
    });
  }
}

const processWeekData = (responses: any[], dateList: string[]) => {
  // 检查是否有任何有效数据
  const hasValidData = responses.some(dayResponses =>
      dayResponses.some((res: any) => res?.data?.flag && res?.data?.data !== null)
  );

  // 如果没有有效数据，使用测试数据
  if (!hasValidData) {
    ElMessage.warning('没有有效数据，已使用测试数据');
    const testData = generateTestData();
    return updateChartsWithWeekData(testData);
  }

  // 初始化聚合数据结构（所有字段都有默认值）
  const weekData = {
    moodTrend: [] as string[],
    hotpointCount: 0,
    categoryDistribution: {} as Record<string, number>,
    emotionDistribution: {
      positive: 0,
      neutral: 0,
      negative: 0
    },
    top10Hotpoints: [] as Array<{name: string, value: number}>,
    categoryEmotion: {} as Record<string, {positive: number, neutral: number, negative: number}>
  };

  // 遍历每天的数据
  responses.forEach((dayResponses, index) => {
    const [res1, res2, res3, res4, res5] = dayResponses;
    const currentDate = dateList[index];

    // 检查当天所有API是否都有有效数据
    const isValidDay = [res1, res2, res3, res4, res5].every(
        res => res?.data?.flag && res?.data?.data !== null && res?.data?.data !== undefined
    );

    if (!isValidDay) {
      console.warn(`日期 ${currentDate} 的数据不完整，跳过处理`);
      return; // 跳过当天数据
    }

    try {
      // 1. 统计热搜总数（安全访问）
      weekData.hotpointCount += res1.data.data.totalCount || 0;

      // 2. 计算情感趋势
      const dayMood = res3.data.data.Positive > res3.data.data.Negative
          ? (res3.data.data.Positive > res3.data.data.Neutral ? 'positive' : 'neutral')
          : (res3.data.data.Neutral > res3.data.data.Negative ? 'neutral' : 'negative');
      weekData.moodTrend.push(dayMood);

      // 3. 聚合情感分布（安全访问）
      weekData.emotionDistribution.positive += res3.data.data.Positive || 0;
      weekData.emotionDistribution.neutral += res3.data.data.Neutral || 0;
      weekData.emotionDistribution.negative += res3.data.data.Negative || 0;

      // 4. 统计分类分布（安全访问）
      if (Array.isArray(res4.data.data.categories)) {
        res4.data.data.categories.forEach((item: any) => {
          weekData.categoryDistribution[item.name] =
              (weekData.categoryDistribution[item.name] || 0) + (item.value || 0);
        });
      }

      // 5. 处理分类情感分布（安全访问）
      if (Array.isArray(res2.data.data.categories)) {
        res2.data.data.categories.forEach((category: string, i: number) => {
          if (!weekData.categoryEmotion[category]) {
            weekData.categoryEmotion[category] = { positive: 0, neutral: 0, negative: 0 };
          }
          weekData.categoryEmotion[category].positive += res2.data.data.positive?.[i] || 0;
          weekData.categoryEmotion[category].neutral += res2.data.data.neutral?.[i] || 0;
          weekData.categoryEmotion[category].negative += res2.data.data.negative?.[i] || 0;
        });
      }

      // 6. 处理Top10热搜（安全访问）
      if (Array.isArray(res5.data.data.titles) && Array.isArray(res5.data.data.durations)) {
        res5.data.data.titles.forEach((title: string, i: number) => {
          const duration = res5.data.data.durations[i] || 0;
          const existing = weekData.top10Hotpoints.find(item => item.name === title);
          if (existing) {
            existing.value += duration;
          } else {
            weekData.top10Hotpoints.push({
              name: title,
              value: duration
            });
          }
        });
      }
    } catch (error) {
      console.error(`处理日期 ${currentDate} 数据时出错:`, error);
    }
  });

  // 处理最终数据展示
  updateChartsWithWeekData(weekData);
};

const updateChartsWithWeekData = (weekData: any) => {
  // 1. 更新统计卡片数据
  hotpointCount.value = weekData.hotpointCount;

  // 计算最频繁的情绪
  const moodCount = weekData.moodTrend.reduce((acc: any, mood: string) => {
    acc[mood] = (acc[mood] || 0) + 1;
    return acc;
  }, {});

  const dominantMood = Object.entries(moodCount).reduce((a, b) => (a[1] as number) > (b[1] as number) ? a : b)[0];
  mood.value = dominantMood === 'positive' ? '积极' : dominantMood === 'neutral' ? '中立' : '消极';
  moodColor.value = dominantMood === 'positive' ? '#67C23A' : dominantMood === 'neutral' ? '#909399' : '#F56C6C';

  // 2. 更新情感分布环形图
  chartData1.value = [
    {
      value: weekData.emotionDistribution.positive,
      name: '积极',
      itemStyle: { color: '#67C23A' }
    },
    {
      value: weekData.emotionDistribution.neutral,
      name: '中立',
      itemStyle: { color: '#909399' }
    },
    {
      value: weekData.emotionDistribution.negative,
      name: '消极',
      itemStyle: { color: '#F56C6C' }
    }
  ];

  // 3. 更新种类分布环形图
  chartData2.value = Object.entries(weekData.categoryDistribution)
      .map(([name, value]) => ({
        name,
        value: value as number,
        itemStyle: { color: getCategoryColor(name) }
      }));

  // 4. 更新热搜持续Top10柱状图
  weekData.top10Hotpoints.sort((a: any, b: any) => b.value - a.value);
  xAxis.value = weekData.top10Hotpoints.slice(0, 10).map((item: any) => item.name);
  yAxis.value = weekData.top10Hotpoints.slice(0, 10).map((item: any) => item.value);

  // 5. 更新分类情感堆叠柱状图
  xAxisData.value = Object.keys(weekData.categoryEmotion);
  yAxisData_Positive.value = xAxisData.value.map(name => weekData.categoryEmotion[name].positive);
  yAxisData_Neutral.value = xAxisData.value.map(name => weekData.categoryEmotion[name].neutral);
  yAxisData_Negative.value = xAxisData.value.map(name => weekData.categoryEmotion[name].negative);

  // 更新所有图表
  nextTick(() => {
    updateChart1();
    updateChart2();
    updateBarChart();
    updateMultiBarChart();
  });
};

// 辅助函数 - 为不同分类生成颜色
const getCategoryColor = (category: string) => {
  const colors = [
    '#FF4500', '#1E90FF', '#32CD32', '#8B0000', '#9932CC',
    '#FF8C00', '#4682B4', '#008000', '#800080', '#A0522D'
  ];
  const index = Math.abs(hashCode(category)) % colors.length;
  return colors[index];
};

// 辅助函数 - 字符串哈希
const hashCode = (str: string) => {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash);
  }
  return hash;
};

// --> 环形图 <--
const chart1 = ref<echarts.ECharts | null>(null);
const chart2 = ref<echarts.ECharts | null>(null);

// 初始化图表
const initChart1 = () => {
  const chartDom = document.getElementById('chart1');
  if (chartDom) {
    chart1.value = echarts.init(chartDom);
    updateChart1(); // 初始化时渲染
  }
}

const initChart2 = () => {
  const chartDom = document.getElementById('chart2');
  if (chartDom) {
    chart2.value = echarts.init(chartDom);
    updateChart2(); // 初始化时渲染
  }
}

// 更新图表数据
const updateChart1 = () => {
  if (!chart1.value) return;

  const newOption = {
    ...option1, // 保留原有配置
    series: [{
      ...option1.series[0],
      data: chartData1.value // 更新数据
    }]
  };

  chart1.value.setOption(newOption);
};

const updateChart2 = () => {
  if (!chart2.value) return;

  const newOption = {
    ...option2, // 保留原有配置
    series: [{
      ...option2.series[0],
      data: chartData2.value // 更新数据
    }]
  };

  chart2.value.setOption(newOption);
};

// 环形图配置
const chartData1 = ref([
  {
    value: 1,
    name: '积极',
    itemStyle: {
      color: '#67C23A' // Element Plus 的成功色（绿色）
    }
  },
  {
    value: 3,
    name: '中立',
    itemStyle: {
      color: '#909399' // Element Plus 的次要色（灰色）
    }
  },
  {
    value: 2,
    name: '消极',
    itemStyle: {
      color: '#F56C6C' // Element Plus 的危险色（红色）
      // 或者使用警告色黄色：#E6A23C
    }
  },
]);

const chartData2 = ref([
  { value: 1, name: '娱乐圈' },
  { value: 3, name: '科技' },
  { value: 2, name: '体育' },
  { value: 4, name: '财经' },
  { value: 5, name: '军事' },
  { value: 3, name: '游戏' },
  { value: 7, name: '艺术' },
  { value: 6, name: '动漫' },
  { value: 2, name: '传统文化' },
  { value: 9, name: '社会' },
  { value: 4, name: '健康' },
  { value: 1, name: '教育' },
  { value: 7, name: '政治' },
  { value: 3, name: '其他' },
]);

// 左侧饼状图设置
const option1 = {
  title: {
    text: '整体热搜情感分布',    // 标题文本
    left: 'center',        // 水平居中
    top: '3%',             // 距离顶部距离
    textStyle: {
      color: '#333',       // 字体颜色
      fontSize: 18,        // 字体大小
      fontWeight: 'bold'   // 加粗
    }
  },
  tooltip: {
    trigger: 'item',
    formatter: (params: any) => {
      return `
        <div style="
          margin: 0;
          text-align: left;  // 全局左对齐
          font-family: Arial, sans-serif; // 统一字体
        ">
          <!-- 标题 -->
          <div style="
            font-size: 14px;
            color: #666;
            border-bottom: 1px solid #eee;
            padding-bottom: 5px;
            margin-bottom: 5px;
          ">
            ${params.seriesName}
          </div>

          <!-- 分类名称 -->
          <div style="
            display: flex;
            align-items: center;
            justify-content: flex-start; // 左对齐flex项
            margin-bottom: 8px;
          ">
            <span style="
              display: inline-block;
              width: 10px;
              height: 10px;
              background: ${params.color};
              border-radius: 50%;
              margin-right: 8px;
              flex-shrink: 0; // 防止图标挤压
            "></span>
            <span style="
              font-weight: bold;
              white-space: nowrap; // 防止换行
            ">
              ${params.name}
            </span>
          </div>

          <!-- 数据行 -->
          <div style="line-height: 1.6">
            <div style="display: flex; justify-content: space-between">
              <span style="color: #999; margin-right: 15px">数量：</span>
              <span style="color: #409EFF">${params.value.toLocaleString()}</span>
            </div>
            <div style="display: flex; justify-content: space-between">
              <span style="color: #999; margin-right: 15px">占比：</span>
              <span style="color: #67C23A">${params.percent.toFixed(2)}%</span>
            </div>
          </div>
        </div>
      `;
    }
  },
  legend: {
    top: '15%',
    left: 'center',
    orient: 'horizontal', // 水平排列
    itemGap: 15          // 图例项间距
  },
  grid: {                // 内容区域留白
    top: '20%',
    bottom: '15%'
  },
  series: [
    {
      name: '对应情感评论分布',
      type: 'pie',
      colorBy: 'data',
      center: ['50%', '60%'],
      radius: [20, 100],
      avoidLabelOverlap: false,
      roseType: 'radius', // 启用南丁格尔玫瑰图
      itemStyle: {
        borderRadius: 5 // 可选圆角
      },
      label: {
        show: false,
        position: 'center'
      },
      emphasis: {
        label: {
          show: false,
          fontSize: 40,
          fontWeight: 'bold'
        }
      },
      labelLine: {
        show: false
      },
      data: chartData1.value
    }
  ]
};

// 右侧饼状图设置
const option2 = {
  title: {
    text: '整体热搜种类分布',    // 标题文本
    left: 'center',        // 水平居中
    top: '3%',             // 距离顶部距离
    textStyle: {
      color: '#333',       // 字体颜色
      fontSize: 18,        // 字体大小
      fontWeight: 'bold'   // 加粗
    }
  },
  tooltip: {
    trigger: 'item',
    formatter: (params: any) => {
      return generateTooltipContent(params); // 使用统一的提示内容生成函数
    }
  },
  legend: {
    right: '5%',
    top: 'center',
    orient: 'vertical',
    itemGap: 15,          // 图例项间距
    formatter: function (name: string) {
      // 自定义截断函数
      const truncate = (str: string, maxLength: number) => {
        return str.length > maxLength ? str.substring(0, maxLength) + '…' : str;
      };

      // 根据容器宽度动态计算最大长度（示例按14px字体估算）
      const maxCharWidth = 10; // 大约10个汉字宽度
      return truncate(name, maxCharWidth);
    },
    tooltip: {
      show: true,
      formatter: ({ name }: { name: string }) => {
        // 在chartData2中查找对应的数据项
        const dataItem = chartData2.value.find(item => item.name === name);
        if (!dataItem) return name;

        // 构造模拟参数对象
        const mockParams = {
          ...dataItem,
          seriesName: '热搜种类分布',
          percent: 0 // 临时占位，后面会计算真实值
        };

        // 计算真实百分比
        const total = chartData2.value.reduce((sum, item) => sum + item.value, 0);
        mockParams.percent = total > 0 ? (mockParams.value / total * 100) : 0;

        return generateTooltipContent(mockParams);
      }
    }
  },
  grid: {                // 内容区域留白
    left: '0%',
    right: '20%',
    top: '20%',
    bottom: '15%',
    containLabel: true
  },
  series: [
    {
      name: '热搜种类分布',
      type: 'pie',
      center: ['48%', '54%'],
      radius: ['10%', '85%'],
      roseType: 'radius', // 启用南丁格尔玫瑰图
      itemStyle: {
        borderRadius: 5 // 可选圆角
      },
      avoidLabelOverlap: true,
      label: {
        show: false,
        position: 'center'
      },
      emphasis: {
        focus: 'self',  // 只高亮当前扇区
        scale: true,    // 放大效果
        scaleSize: 5,   // 放大尺寸
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        },
        label: {
          show: false,
          fontSize: 40,
          fontWeight: 'bold'
        }
      },
      blurScope: 'coordinateSystem',  // 淡化其他扇区
      labelLine: {
        show: false
      },
      data: chartData2.value
    }
  ]
};

// --> 柱状图 <--
let barChart: ECharts | null = null;

const xAxis = ref([1, 2, 3, 4, 5, 6, 7])
const yAxis = ref([1, 2, 3, 4, 5, 6, 7])

const updateBarChart = () => {
  if (barChart) {
    barChart.dispose();
    barChart = null;
  }

  // 创建新实例
  const chartDom = document.getElementById('barChart');
  if (!chartDom) return;

  barChart = echarts.init(chartDom);
  barChart.setOption(barChartOption.value);
}

const barChartOption = computed(() => ({
  // tooltip 配置
  tooltip: {
    trigger: 'item',       // 触发方式：数据项
    backgroundColor: '#333',
    borderColor: '#666',
    textStyle: {
      color: '#fff',
      fontSize: 14
    },
    // 自定义提示内容
    formatter: (params: any) => {
      return `
        <div style="margin:5px">
          <div style="font-size:16px;font-weight:bold;color:#409EFF">
            ${params.name}
          </div>
          <div style="margin-top:8px">
            <span style="display:inline-block;width:60px">热度值：</span>
            <span style="color:#ffd700">${params.value}</span>
          </div>
        </div>
      `;
    }
  },
  grid: {
    top: '5%',    // 顶部留空比例
    bottom: '25%', // 底部留空比例
    // containLabel: true // 包含坐标轴标签
  },
  xAxis: {
    type: 'category',
    data: xAxis.value,
    axisLabel: {
      // 截断文本并添加省略号
      formatter: (value: string) => {
        const maxLength = 6 // 最大显示字符数（根据实际宽度调整）
        return value.length > maxLength
            ? `${value.substring(0, maxLength)}...`
            : value
      },
      rotate: 45,          // 倾斜45度防止重叠
      interval: 0,          // 强制显示所有标签
      textStyle: {
        color: '#666',
        fontSize: 12
      }
    }
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      data: yAxis.value,
      type: 'bar',
      showBackground: true,
      backgroundStyle: {
        color: 'rgba(180, 180, 180, 0.2)'
      },
    }
  ]
}));

// --> 堆叠柱状图 <--
let multiBarChart: ECharts | null = null;

const xAxisData = ref(['1', '2', '3', '4', '5', '6', '7'])
const yAxisData_Positive = ref([1, 5, 7, 6, 5, 11, 8])
const yAxisData_Negative = ref([15, 4, 17, 12, 9, 5, 8])
const yAxisData_Neutral = ref([6, 8, 3, 15, 12, 4, 18])


// 初始化柱状图
const updateMultiBarChart = () => {
  // 销毁旧实例
  if (multiBarChart) {
    multiBarChart.dispose();
    multiBarChart = null;
  }

  // 创建新实例
  const chartDom = document.getElementById('multiBarChart');
  if (!chartDom) return;

  multiBarChart = echarts.init(chartDom);
  multiBarChart.setOption(multiBarChartOption.value);
}

const multiBarChartOption = computed(() => ({
  // tooltip 配置
  tooltip: {
    trigger: 'axis',  // 触发方式：轴
    axisPointer: {   // 添加阴影指示器
      type: 'shadow' // 官方示例的阴影样式
    },
    backgroundColor: '#333',
    borderColor: '#666',
    textStyle: {
      color: '#fff',
      fontSize: 14
    },
    // 自定义提示内容
    formatter: function (params: any) {
      // 计算当前分类所有系列值的总和
      const total = params.reduce((sum: number, item: any) => sum + item.value, 0);
      let tipHtml = `<div style="text-align: left; margin: 5px">`;
      params.forEach((item: any) => {
        // 计算当前值在总和中占比（保留两位小数）
        const percent = total === 0 ? '0.00%' : `${((item.value / total) * 100).toFixed(2)}%`;
        tipHtml += `
          <div style="display: flex; align-items: center;">
            <span style="
              display: inline-block;
              width: 10px;
              height: 10px;
              background: ${item.color};
              margin-right: 8px;
              border-radius: 2px;">
            </span>
            <span style="flex: 1">
              ${item.seriesName}：
              <span style="color: #ffd700; margin-left: 8px">${item.value}</span>
              <span style="color: #67C23A; margin-left: 8px;">(${percent})</span>
            </span>
          </div>
        `
      })
      tipHtml += `</div>`
      return tipHtml
    }
  },
  legend: {
    data: ['积极', '中立', '消极'], // 系列名称数组（需与series中的name对应）
    top: '5%',         // 位置：顶部
    textStyle: {
      color: '#606266' // 使用Element Plus的文本颜色
    }
  },
  grid: {
    top: '25%',    // 顶部留空比例
    bottom: '15%', // 底部留空比例
    containLabel: true // 包含坐标轴标签
  },
  xAxis: {
    type: 'category',
    data: xAxisData.value,
    axisLabel: {
      // 截断文本并添加省略号
      formatter: (value: string) => {
        const maxLength = 6 // 最大显示字符数（根据实际宽度调整）
        return value.length > maxLength
            ? `${value.substring(0, maxLength)}...`
            : value
      },
      rotate: 45,          // 倾斜45度防止重叠
      interval: 0,          // 强制显示所有标签
      textStyle: {
        color: '#666',
        fontSize: 12
      }
    }
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: '积极',       // 新增系列名称（对应legend）
      type: 'bar',
      stack: 'judge',    // 保持原有堆叠组
      emphasis: {        // 新增聚焦效果
        focus: 'series'  // 系列级高亮（官方交互效果）
      },
      data: yAxisData_Positive.value,  // 保持原有数据传递方式
      itemStyle: {       // 新增颜色配置
        color: '#67C23A' // 与饼图颜色一致
      },
      showBackground: true,
      backgroundStyle: {
        color: 'rgba(180, 180, 180, 0.2)'
      },
    },
    {
      name: '中立',       // 新增系列名称（对应legend）
      type: 'bar',
      stack: 'judge',    // 保持原有堆叠组
      emphasis: {        // 新增聚焦效果
        focus: 'series'  // 系列级高亮（官方交互效果）
      },
      data: yAxisData_Neutral.value,  // 保持原有数据传递方式
      itemStyle: {       // 新增颜色配置
        color: '#909399' // 与饼图颜色一致
      },
      showBackground: true,
      backgroundStyle: {
        color: 'rgba(180, 180, 180, 0.2)'
      },
    },
    {
      name: '消极',       // 新增系列名称（对应legend）
      type: 'bar',
      stack: 'judge',    // 保持原有堆叠组
      emphasis: {        // 新增聚焦效果
        focus: 'series'  // 系列级高亮（官方交互效果）
      },
      data: yAxisData_Negative.value,  // 保持原有数据传递方式
      itemStyle: {       // 新增颜色配置
        color: '#F56C6C' // 与饼图颜色一致
      },
      showBackground: true,
      backgroundStyle: {
        color: 'rgba(180, 180, 180, 0.2)'
      },
    }
  ]
}));
</script>

<style scoped lang="scss">
.dashboard-card {
  margin-bottom: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);

  :deep(.el-card__body) {
    padding: 0;
  }
}

.chart-container {
  width: 40vw;             // 保持原有宽度设置
  height: 29.5vh;            // 保持原有高度设置
  margin: 0 auto;          // 水平居中
  position: relative;      // 为子元素绝对定位提供基准
}

.chart-wrapper {
  width: 100%;
  height: 100%;
  display: flex;           // 启用弹性布局
  justify-content: center; // 水平居中
  align-items: center;     // 垂直居中
}

// card标题样式
.card-header {
  padding: 18px 24px;  // 设置内边距
  border-bottom: 1px solid #ebeef5; // 添加底部边框

  // 定义子元素样式
  .card-title {
    font-size: 16px;  // 字体大小
    font-weight: 600; // 字体粗细
    color: #303133; // 字体颜色
  }
}
</style>